/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainWindow.java
 *
 * Created on Aug 5, 2011, 9:11:12 AM
 */
package org.bennedum.SimpleMCClient;

import java.awt.EventQueue;
import java.text.DateFormat;
import java.util.Date;

/**
 *
 * @author frdfsnlght <frdfsnlght@gmail.com>
 */
public class MainWindow extends javax.swing.JFrame {

    private static final long MOVEMENT_INTERVAL = 100;
    
    /** Creates new form MainWindow */
    public MainWindow() {
        initComponents();
        setLocationRelativeTo(null);
        movementThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (movementThreadRun) {
                    applyMovement();
                    try {
                        Thread.sleep(MOVEMENT_INTERVAL);
                    } catch (InterruptedException e) {}
                }
            }
        });
        movementThread.start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.JPanel controlPanel = new javax.swing.JPanel();
        disconnectButton = new javax.swing.JButton();
        javax.swing.JLabel timeLabel = new javax.swing.JLabel();
        javax.swing.JPanel movementPanel = new javax.swing.JPanel();
        moveBackwardButton = new javax.swing.JButton();
        turnRightButton = new javax.swing.JButton();
        moveUpButton = new javax.swing.JButton();
        moveDownButton = new javax.swing.JButton();
        moveForwardButton = new javax.swing.JButton();
        turnLeftButton = new javax.swing.JButton();
        javax.swing.JLabel positionLabel = new javax.swing.JLabel();
        timeField = new javax.swing.JTextField();
        positionField = new javax.swing.JTextField();
        javax.swing.JPanel chatPanel = new javax.swing.JPanel();
        javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
        chatInput = new javax.swing.JTextField();
        javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
        chatOutput = new javax.swing.JTextArea();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("SimpleMCClient");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        disconnectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/slash.png"))); // NOI18N
        disconnectButton.setText("Disconnect");
        disconnectButton.setToolTipText("Disconnect from the server");
        disconnectButton.setActionCommand("disconnect");
        disconnectButton.setDefaultCapable(false);
        disconnectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                disconnectButtonActionPerformed(evt);
            }
        });

        timeLabel.setText("Time:");
        timeLabel.setFocusable(false);
        timeLabel.setPreferredSize(null);

        movementPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Movement"));

        moveBackwardButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/arrow-270.png"))); // NOI18N
        moveBackwardButton.setToolTipText("Move backward");

        turnRightButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/arrow-circle-225.png"))); // NOI18N
        turnRightButton.setToolTipText("Turn right");

        moveUpButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/arrow-skip-090.png"))); // NOI18N
        moveUpButton.setToolTipText("Move up");

        moveDownButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/arrow-skip-270.png"))); // NOI18N
        moveDownButton.setToolTipText("Move down");

        moveForwardButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/arrow-090.png"))); // NOI18N
        moveForwardButton.setToolTipText("Move forward");

        turnLeftButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/bennedum/SimpleMCClient/resources/arrow-circle-315-left.png"))); // NOI18N
        turnLeftButton.setToolTipText("Turn left");

        javax.swing.GroupLayout movementPanelLayout = new javax.swing.GroupLayout(movementPanel);
        movementPanel.setLayout(movementPanelLayout);
        movementPanelLayout.setHorizontalGroup(
            movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(movementPanelLayout.createSequentialGroup()
                .addGroup(movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(movementPanelLayout.createSequentialGroup()
                        .addComponent(turnLeftButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(turnRightButton))
                    .addComponent(moveBackwardButton, javax.swing.GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
                    .addComponent(moveForwardButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(moveDownButton)
                    .addComponent(moveUpButton)))
        );
        movementPanelLayout.setVerticalGroup(
            movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(movementPanelLayout.createSequentialGroup()
                .addGroup(movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(movementPanelLayout.createSequentialGroup()
                        .addComponent(moveForwardButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(turnRightButton)
                            .addComponent(turnLeftButton)))
                    .addComponent(moveUpButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(movementPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(moveDownButton)
                    .addComponent(moveBackwardButton)))
        );

        positionLabel.setText("Pos:");

        timeField.setEditable(false);
        timeField.setOpaque(false);

        positionField.setEditable(false);
        positionField.setOpaque(false);

        javax.swing.GroupLayout controlPanelLayout = new javax.swing.GroupLayout(controlPanel);
        controlPanel.setLayout(controlPanelLayout);
        controlPanelLayout.setHorizontalGroup(
            controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(controlPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(controlPanelLayout.createSequentialGroup()
                        .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(timeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(positionLabel))
                        .addGap(18, 18, 18)
                        .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(timeField, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(positionField, javax.swing.GroupLayout.PREFERRED_SIZE, 297, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(disconnectButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(47, 47, 47)
                .addComponent(movementPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        controlPanelLayout.setVerticalGroup(
            controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(controlPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(movementPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(controlPanelLayout.createSequentialGroup()
                        .addComponent(disconnectButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(timeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(timeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(controlPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(positionLabel)
                            .addComponent(positionField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );

        jLabel1.setText("Chat:");

        chatInput.setToolTipText("Enter a chat message");
        chatInput.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                chatInputKeyTyped(evt);
            }
        });

        chatOutput.setColumns(20);
        chatOutput.setEditable(false);
        chatOutput.setFont(new java.awt.Font("Tahoma", 0, 11));
        chatOutput.setRows(5);
        chatOutput.setEnabled(false);
        chatOutput.setFocusable(false);
        jScrollPane1.setViewportView(chatOutput);

        javax.swing.GroupLayout chatPanelLayout = new javax.swing.GroupLayout(chatPanel);
        chatPanel.setLayout(chatPanelLayout);
        chatPanelLayout.setHorizontalGroup(
            chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(chatPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(chatInput, javax.swing.GroupLayout.DEFAULT_SIZE, 522, Short.MAX_VALUE)
                .addContainerGap())
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 579, Short.MAX_VALUE)
        );
        chatPanelLayout.setVerticalGroup(
            chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(chatPanelLayout.createSequentialGroup()
                .addGroup(chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(chatInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 219, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(chatPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(controlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 131, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(chatPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void disconnectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_disconnectButtonActionPerformed
        Main.client.disconnect();
    }//GEN-LAST:event_disconnectButtonActionPerformed

    private void chatInputKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_chatInputKeyTyped
        if (evt.getKeyChar() != '\n') return;
        String message = chatInput.getText().trim();
        chatInput.setText("");
        if (message.isEmpty()) return;
        Main.client.sendChat(message);
    }//GEN-LAST:event_chatInputKeyTyped

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        Main.client.disconnect();
    }//GEN-LAST:event_formWindowClosing

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField chatInput;
    private javax.swing.JTextArea chatOutput;
    private javax.swing.JButton disconnectButton;
    private javax.swing.JButton moveBackwardButton;
    private javax.swing.JButton moveDownButton;
    private javax.swing.JButton moveForwardButton;
    private javax.swing.JButton moveUpButton;
    private javax.swing.JTextField positionField;
    private javax.swing.JTextField timeField;
    private javax.swing.JButton turnLeftButton;
    private javax.swing.JButton turnRightButton;
    // End of variables declaration//GEN-END:variables

    private Thread movementThread;
    private boolean movementThreadRun = true;
    private DateFormat dateFormat = DateFormat.getTimeInstance(DateFormat.LONG);
    private int lastSecond = 0;
    
    public void chatOut(final String fmt, final Object ... args) {
        if (! EventQueue.isDispatchThread()) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    chatOut(fmt, args);
                }
            });
            return;
        }
        chatOutput.append(String.format("[%s] %s\n",
                dateFormat.format(new Date()),
                String.format(fmt, args)));
    }

    public void onTimeChanged(long time) {
        int second = (int)(time % 1000 % 60);
        if (second == lastSecond) return;
        lastSecond = second;
        int hour = (int)(((time / 1000) + 6) % 24);
        int minute = (int)((time % 1000) * 60 / 1000);
        final String t = String.format("%02d:%02d:%02d", hour, minute, second);
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                timeField.setText(t);
            }
        });
    }

    public void onPositionChanged(final double x, final double y, final double z, final float yaw, final float pitch) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                positionField.setText(String.format("x=%1.2f y=%1.2f z=%1.2f yaw=%1.2f pit=%1.2f", x, y, z, yaw, pitch));
            }
        });
    }
    
    @Override
    public void dispose() {
        movementThreadRun = false;
        try {
            movementThread.join();
        } catch (InterruptedException e) {}
        super.dispose();
    }
    
    private void applyMovement() {
        if (turnRightButton.getModel().isPressed())
            Main.client.setYaw(Main.client.getYaw() + (float)5);
        if (turnLeftButton.getModel().isPressed())
            Main.client.setYaw(Main.client.getYaw() - (float)5);
        if (moveForwardButton.getModel().isPressed()) {
            double yaw = Main.client.getYaw() * Math.PI / 180;
            Main.client.setX(Main.client.getX() + (Math.cos(yaw) * 0.5));
            Main.client.setZ(Main.client.getZ() + (Math.sin(yaw) * 0.5));
        }
        if (moveBackwardButton.getModel().isPressed()) {
            double yaw = Main.client.getYaw() * Math.PI / 180;
            Main.client.setX(Main.client.getX() - (Math.cos(yaw) * 0.5));
            Main.client.setZ(Main.client.getZ() - (Math.sin(yaw) * 0.5));
        }
        if (moveUpButton.getModel().isPressed())
            Main.client.setY(Main.client.getY() + 0.5);
        if (moveDownButton.getModel().isPressed())
            Main.client.setY(Main.client.getY() - 0.5);
    }
    
}
